package store

import (
	"github.com/project-flogo/core/data/coerce"
	"github.com/tidwall/gjson"
)

type Settings struct {
	Addr      string `md:"addr,required" json:"addr,omitempty"`
	DB        int    `md:"db,required" json:"db,omitempty"`
	Password  string `md:"password" json:"password,omitempty"`
	KeyPrefix string `md:"keyPrefix" json:"keyPrefix,omitempty"`
}

type Input struct {
	Op            string          `md:"op,required" json:"op,omitempty"`
	EdgeChannelID string          `md:"metricId" json:"metricId,omitempty"`
	Data          EdgeChannelData `md:"data" json:"data,omitempty"`
}

func (r *Input) ToMap() map[string]interface{} {
	return map[string]interface{}{
		"op":            r.Op,
		"edgeChannelId": r.EdgeChannelID,
		"data":          toMap(r.Data),
	}
}

func (r *Input) FromMap(values map[string]interface{}) error {
	op, err := coerce.ToString(values["op"])
	if err != nil {
		return err
	}
	r.Op = op

	edgeChannelId, err := coerce.ToString(values["edgeChannelId"])
	if err != nil {
		return err
	}
	r.EdgeChannelID = edgeChannelId

	m, err := coerce.ToObject(values["data"])
	if err != nil {
		return err
	}
	data, err := fromMap(m)
	if err != nil {
		return err
	}
	r.Data = data

	return nil
}

type Output struct {
	Err  string          `md:"err" json:"err,omitempty"`
	Data EdgeChannelData `md:"data" json:"data,omitempty"`
}

func (r *Output) ToMap() map[string]interface{} {
	return map[string]interface{}{
		"err":  r.Err,
		"data": toMap(r.Data),
	}
}

func (r *Output) FromMap(values map[string]interface{}) error {
	str, err := coerce.ToString(values["err"])
	if err != nil {
		return err
	}
	r.Err = str

	m, err := coerce.ToObject(values["data"])
	if err != nil {
		return err
	}
	data, err := fromMap(m)
	if err != nil {
		return err
	}
	r.Data = data

	return nil
}

func toMap(m EdgeChannelData) map[string]interface{} {
	return map[string]interface{}{
		"id":        m.ID,
		"timestamp": m.Timestamp,
		"value":     m.Value.Raw,
	}
}

func fromMap(values map[string]interface{}) (EdgeChannelData, error) {
	m := EdgeChannelData{}
	id, err := coerce.ToString(values["id"])
	if err != nil {
		return m, err
	}
	timestamp, err := coerce.ToInt64(values["timestamp"])
	if err != nil {
		return m, err
	}
	str, err := coerce.ToString(values["value"])
	if err != nil {
		return m, err
	}

	m.ID = id
	m.Timestamp = timestamp
	m.Value = gjson.Parse(str)

	return m, nil
}
